#include "uart_hw.h"
#include "gd32e10x_usart.h"
#include "gd32e10x_dma.h"
#include "globalDef.h"
#include "L610.h"


extern uint8_t getLowPowerSta(void);


extern u8 rxL610Buf[MAX_RECV_L610_IRT_LEN];

extern u8 rxPCBuf[MAX_RECV_L610_IRT_LEN];






void initUart1DMA(uint32_t baud)
{
	uint32_t com = USART1;
	
	dma_parameter_struct dma_init_struct;
	
	/* configure COM1 */
	rcu_periph_clock_enable(RCU_GPIOA);
	//rcu_periph_clock_enable(RCU_AF);
	
	/* enable USART clock */
  rcu_periph_clock_enable(RCU_USART1);
	/* connect port to USARTx_Tx */
	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_2);

	/* connect port to USARTx_Rx */
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_3);
	

	/* USART configure */
	usart_deinit(com);
	usart_baudrate_set(com, baud);
	usart_parity_config(com,USART_PM_NONE);
	usart_word_length_set(com,USART_WL_8BIT);
	usart_stop_bit_set(com,USART_STB_1BIT);
	usart_receive_config(com, USART_RECEIVE_ENABLE);
	usart_transmit_config(com, USART_TRANSMIT_ENABLE);
	usart_enable(com);
	
		
	//DMA 设置
	
  /* enable DMA1 */
  rcu_periph_clock_enable(RCU_DMA0);
	
	/* deinitialize DMA channel2 (USART2 rx) */
	dma_deinit(DMA0, DMA_CH5);
	dma_struct_para_init(&dma_init_struct);
	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
	dma_init_struct.memory_addr = (uint32_t)rxL610Buf;
	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
	dma_init_struct.number = MAX_RECV_L610_IRT_LEN;
	dma_init_struct.periph_addr = (uint32_t)&USART_DATA(com);
	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
	dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
	dma_init(DMA0, DMA_CH5, &dma_init_struct);
	/* configure DMA mode */
	dma_circulation_enable(DMA0, DMA_CH5);        
	/* enable DMA channel2 */
	dma_channel_enable(DMA0, DMA_CH5);
	
	
	usart_enable(com);
	

	/* USART DMA enable for transmission and reception */
  //usart_dma_transmit_config(com, USART_DENT_ENABLE);
  usart_dma_receive_config(com, USART_DENR_ENABLE);


		
}

//建议每秒调用1次，防止错误阻止接收
void clear_dma0_ch5_err(void)
{
	if (dma_flag_get(DMA0, DMA_CH5, DMA_FLAG_ERR) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH5, DMA_FLAG_ERR);
	}
	
	if (dma_flag_get(DMA0, DMA_CH5, DMA_FLAG_FTF) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH5, DMA_FLAG_FTF);
	}
	
	if (dma_flag_get(DMA0, DMA_CH5, DMA_FLAG_HTF) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH5, DMA_FLAG_HTF);
	}
	
	
}



/*
函数名称：initUsart0
功能：初始化
输入参数：波特率
输出参数：无
*/
void initUart0DMA(uint32_t baud)
{
	uint32_t com = USART0;
	dma_parameter_struct dma_init_struct;
	
	
	/* configure COM1 */
	rcu_periph_clock_enable(RCU_GPIOA);
	//rcu_periph_clock_enable(RCU_AF);
	
	/* enable USART clock */
  rcu_periph_clock_enable(RCU_USART0);
	/* connect port to USARTx_Tx */
	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_9);

	/* connect port to USARTx_Rx */
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_10);

	/* USART configure */
	usart_deinit(com);
	usart_baudrate_set(com, baud);
	usart_parity_config(com,USART_PM_NONE);
	usart_word_length_set(com,USART_WL_8BIT);
	usart_stop_bit_set(com,USART_STB_1BIT);
	usart_receive_config(com, USART_RECEIVE_ENABLE);
	usart_transmit_config(com, USART_TRANSMIT_ENABLE);
	usart_enable(com);
	
	//nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
	//nvic_irq_enable(USART0_IRQn, 1, 0);
	
	//nvic_irq_enable(USART0_IRQn, 0, 0);	
	
	/* enable USART TBE interrupt */  
	//usart_interrupt_enable(USART0, USART_INT_TBE);	//发送寄存器空中断
	//usart_interrupt_enable(com, USART_INT_RBNE);	//接收寄存器非空中断
	
	//DMA 设置
	
  /* enable DMA1 */
  rcu_periph_clock_enable(RCU_DMA0);
	
	/* deinitialize DMA channel4 (USART0 rx) */
	dma_deinit(DMA0, DMA_CH4);
	dma_struct_para_init(&dma_init_struct);
	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
	dma_init_struct.memory_addr = (uint32_t)rxPCBuf;
	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
	dma_init_struct.number = MAX_RECV_L610_IRT_LEN;
	dma_init_struct.periph_addr = (uint32_t)&USART_DATA(com);
	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
	dma_init_struct.priority = DMA_PRIORITY_HIGH;
	dma_init(DMA0, DMA_CH4, &dma_init_struct);
	/* configure DMA mode */
	dma_circulation_enable(DMA0, DMA_CH4);        
	/* enable DMA channel4 */
	dma_channel_enable(DMA0, DMA_CH4);
	
	
	usart_enable(com);
	
	/* USART DMA enable for transmission and reception */
  //usart_dma_transmit_config(com, USART_DENT_ENABLE);
  usart_dma_receive_config(com, USART_DENR_ENABLE);
		
}

//建议每秒调用1次，防止错误阻止接收
void clear_dma0_ch4_err(void)
{
	if (dma_flag_get(DMA0, DMA_CH4, DMA_FLAG_ERR) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH4, DMA_FLAG_ERR);
	}
	
	if (dma_flag_get(DMA0, DMA_CH4, DMA_FLAG_FTF) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH4, DMA_FLAG_FTF);
	}
	
	if (dma_flag_get(DMA0, DMA_CH4, DMA_FLAG_HTF) == SET)
	{
		dma_flag_clear(DMA0, DMA_CH4, DMA_FLAG_HTF);
	}
}




/*
函数名称：initUsart0
功能：初始化
输入参数：波特率
输出参数：无
*/

void initUart0(uint32_t baud)
{
	uint32_t com = USART0;
	/* USART interrupt configuration */
	//nvic_irq_enable(USART0_IRQn, 0, 0);
	
	/* configure COM1 */
	rcu_periph_clock_enable(RCU_GPIOA);
	//rcu_periph_clock_enable(RCU_AF);
	
	/* enable USART clock */
  rcu_periph_clock_enable(RCU_USART0);
	/* connect port to USARTx_Tx */
	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_9);

	/* connect port to USARTx_Rx */
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_10);

	/* USART configure */
	usart_deinit(com);
	usart_baudrate_set(com, baud);
	usart_parity_config(com,USART_PM_NONE);
	usart_word_length_set(com,USART_WL_8BIT);
	usart_stop_bit_set(com,USART_STB_1BIT);
	usart_receive_config(com, USART_RECEIVE_ENABLE);
	usart_transmit_config(com, USART_TRANSMIT_ENABLE);
	usart_enable(com);
	
	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
	nvic_irq_enable(USART0_IRQn, 1, 0);
	
	//nvic_irq_enable(USART0_IRQn, 0, 0);	
	
	/* enable USART TBE interrupt */  
	//usart_interrupt_enable(USART0, USART_INT_TBE);	//发送寄存器空中断
	usart_interrupt_enable(com, USART_INT_RBNE);	//接收寄存器非空中断
	
	usart_enable(com);
}


//串口2
void initUart2(uint32_t baud)
{
	uint32_t com = USART2;
	/* USART interrupt configuration */
	//nvic_irq_enable(USART0_IRQn, 0, 0);
	
	/* configure COM1 */
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_AF);
	
	/* enable USART clock */
  rcu_periph_clock_enable(RCU_USART2);
	/* connect port to USARTx_Tx */
	gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_10);

	/* connect port to USARTx_Rx */
	gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_11);

	/* USART configure */
	usart_deinit(com);
	usart_baudrate_set(com, baud);
	usart_parity_config(com,USART_PM_NONE);
	usart_word_length_set(com,USART_WL_8BIT);
	usart_stop_bit_set(com,USART_STB_1BIT);

	usart_receive_config(com, USART_RECEIVE_ENABLE);
	
	usart_transmit_config(com, USART_TRANSMIT_ENABLE);
	usart_enable(com);
	

	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
	nvic_irq_enable(USART2_IRQn, 2, 0);
	
	/* enable USART TBE interrupt */  
	//usart_interrupt_enable(USART2, USART_INT_TBE);	//发送寄存器空中断
	usart_interrupt_enable(com, USART_INT_RBNE);	//接收寄存器非空中断
	

	
	usart_enable(com);
}


//写串口2
//出错返回1，成功返回0
uint32_t writeUart2(uint8_t * pDa, uint32_t len)
{
	return writeUart(USART2, pDa, len);
		
}

//写串口2
//出错返回1，成功返回0
uint32_t writeUart0OneByte(uint8_t Da)
{
	uint32_t dlyCnt;	//防止死循环
	
	dlyCnt = 0;
	while(RESET == usart_flag_get(USART0, USART_FLAG_TBE))
	{
		dlyCnt++;
		if (dlyCnt > (500000))
		{
			break;
		}
	}
	
	usart_data_transmit(USART0, Da);
	return 0;
}


//写串口2
//出错返回1，成功返回0
uint32_t writeUart0(uint8_t * pDa, uint32_t len)
{
	return writeUart(USART0, pDa, len);
}

uint32_t writeUart1(uint8_t * pDa, uint32_t len)
{
	return writeUart(USART1, pDa, len);
		
}



//写串口2
//出错返回1，成功返回0
uint32_t writeUart(uint32_t usart_periph, uint8_t * pDa, uint32_t len)
{
	uint32_t i;
	uint32_t dlyCnt;	//防止死循环
	
	#if _EN_DisableUartWhenSleep
	if (getLowPowerSta() == 0x01)
	{
		return 0;
	}
	#endif
	
	for(i=0;i<len;i++)
	{
		usart_data_transmit(usart_periph, pDa[i]);
		dlyCnt = 0;
		while(RESET == usart_flag_get(usart_periph, USART_FLAG_TBE))
		{
			dlyCnt++;
			if (dlyCnt > (50000))
			{
				break;
			}
		}
	}
	
	if (i < len)
	{
		//没写完就返回1
		return 1;
	}
	
	return 0;
		
}






